home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume2
/
util
/
dres.3
< prev
next >
Wrap
Text File
|
1988-10-25
|
32KB
|
1,385 lines
Path: xanth!nic.MR.NET!umn-d-ub!rutgers!mailrus!ulowell!page
From: page@swan.ulowell.edu (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v02i018: dres - an object-oriented resource library, Part03/03
Message-ID: <9823@swan.ulowell.edu>
Date: 25 Oct 88 00:56:26 GMT
Organization: University of Lowell, Computer Science Dept.
Lines: 1374
Approved: page@swan.ulowell.edu
Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
Posting-number: Volume 2, Issue 18
Archive-name: util/dres.3
# This is a shell archive. Remove anything before this line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
# README
# core/TODO
# core/funcs.reg
# core/libfuncs.h
# core/libtag.asm
# core/Makefile
# core/func.def
# core/library.c
# libref.c
#
if `test ! -s README`
then
echo "writing README"
cat > README << '\Rogue\Monster\'
The makefile is in core. CD into core and then 'make'. Make will fist
compile libref.c which is used to generate the link library and library
function array.
\Rogue\Monster\
else
echo "will not over write README"
fi
if [ `wc -c README | awk '{printf $1}'` -ne 163 ]
then
echo `wc -c README | awk '{print "Got " $1 ", Expected " 163}'`
fi
if `test ! -d core`
then
mkdir core
echo "mkdir core"
fi
if `test ! -s core/TODO`
then
echo "writing core/TODO"
cat > core/TODO << '\Rogue\Monster\'
add dos.library to list of libraries....
\Rogue\Monster\
else
echo "will not over write core/TODO"
fi
if [ `wc -c core/TODO | awk '{printf $1}'` -ne 43 ]
then
echo `wc -c core/TODO | awk '{print "Got " $1 ", Expected " 43}'`
fi
if `test ! -s core/funcs.reg`
then
echo "writing core/funcs.reg"
cat > core/funcs.reg << '\Rogue\Monster\'
# Q interrupts
AFUNC= OpenQInts -
AFUNC= CloseQInts A0
AFUNC= SetQPri D0/D1
AFUNC= SetQVector D0/D1/D2/D3/A0
AFUNC= NULL -
AFUNC= NULL -
AFUNC= NULL -
AFUNC= NULL -
# List functions
AFUNC= GetHead A0
AFUNC= GetTail A0
AFUNC= GetSucc A0
AFUNC= GetPred A0
AFUNC= GetHeadOff D0/D1
AFUNC= GetTailOff D0/D1
AFUNC= GetSuccOff D0/D1
AFUNC= GetPredOff D0/D1
AFUNC= EnqueueLong D0/D1/D2/D4
AFUNC= EnqueueOffLong D0/D1/D2/D3/D4
AFUNC= SearchFwdNode D0/D1/A1
AFUNC= SearchRvsNode D0/D1/A1
AFUNC= SearchFwdList D0/D1/A1
AFUNC= SearchRvsList D0/D1/A1
AFUNC= SearchFwdNodeOff D0/D1/A0/A1
AFUNC= SearchRvsNodeOff D0/D1/A0/A1
AFUNC= SearchFwdListOff D0/D1/A0/A1
AFUNC= SearchRvsListOff D0/D1/A0/A1
AFUNC= NULL -
AFUNC= NULL -
AFUNC= NULL -
AFUNC= NULL -
# Memory functions
AFUNC= BZero D0/D1
AFUNC= BSet D0/D1/A0
AFUNC= BMov D0/D1/A0
AFUNC= BCmp D0/D1/A0
AFUNC= NULL -
AFUNC= NULL -
AFUNC= NULL -
AFUNC= NULL -
# Misc. Functions
AFUNC= WildCmp D0/D1
AFUNC= WaitMsg A0
AFUNC= CheckMsg A0
AFUNC= CheckPort A0
AFUNC= LockAddr A0
AFUNC= LockAddrB D0/A0
AFUNC= UnLockAddr A0
AFUNC= UnLockAddrB D0/A0
AFUNC= DoSyncMsg A0/A1
AFUNC= FindName2 D0/A0
# placed in res.c
CFUNC= GetTaskData D0/D1
CFUNC= FreeTaskData D0
CFUNC= DateToS D0/D1/A0
CFUNC= SetFileDate D0/D1
CFUNC= NULL -
CFUNC= NULL -
CFUNC= NULL -
CFUNC= NULL -
# IPC functions
CFUNC= OpenIPC D0/D1
CFUNC= CloseIPC D0
CFUNC= SendIPC D0/D1/D2/A0
CFUNC= SendIPC2 D0/D1
CFUNC= ReplyIPC D0/D1/D2/A0
CFUNC= FreeIPC D0
CFUNC= DoIPC2 D0/D1/D2/A0
CFUNC= ParseCmd D0/D1/D2/D3/D4/A0
CFUNC= FreeParseCmd D0
CFUNC= NULL D0
CFUNC= NULL -
CFUNC= NULL -
CFUNC= NULL -
# Resource Library functions
\Rogue\Monster\
else
echo "will not over write core/funcs.reg"
fi
if [ `wc -c core/funcs.reg | awk '{printf $1}'` -ne 1944 ]
then
echo `wc -c core/funcs.reg | awk '{print "Got " $1 ", Expected " 1944}'`
fi
if `test ! -s core/libfuncs.h`
then
echo "writing core/libfuncs.h"
cat > core/libfuncs.h << '\Rogue\Monster\'
/*
* Machine Generated Library Vectors
*/
#ifndef NULL
#define NULL 0L
#endif
extern long _LibOpen(), _LibClose(), _LibExpunge();
extern long lOpenQInts();
extern long lCloseQInts();
extern long lSetQPri();
extern long lSetQVector();
extern long lGetHead();
extern long lGetTail();
extern long lGetSucc();
extern long lGetPred();
extern long lGetHeadOff();
extern long lGetTailOff();
extern long lGetSuccOff();
extern long lGetPredOff();
extern long lEnqueueLong();
extern long lEnqueueOffLong();
extern long lSearchFwdNode();
extern long lSearchRvsNode();
extern long lSearchFwdList();
extern long lSearchRvsList();
extern long lSearchFwdNodeOff();
extern long lSearchRvsNodeOff();
extern long lSearchFwdListOff();
extern long lSearchRvsListOff();
extern long lBZero();
extern long lBSet();
extern long lBMov();
extern long lBCmp();
extern long lWildCmp();
extern long lWaitMsg();
extern long lCheckMsg();
extern long lCheckPort();
extern long lLockAddr();
extern long lLockAddrB();
extern long lUnLockAddr();
extern long lUnLockAddrB();
extern long lDoSyncMsg();
extern long lFindName2();
extern long _lGetTaskData();
extern long _lFreeTaskData();
extern long _lDateToS();
extern long _lSetFileDate();
extern long _lOpenIPC();
extern long _lCloseIPC();
extern long _lSendIPC();
extern long _lSendIPC2();
extern long _lReplyIPC();
extern long _lFreeIPC();
extern long _lDoIPC2();
extern long _lParseCmd();
extern long _lFreeParseCmd();
/*
* -30-6*X
*/
long (*LibVectors[])() = {
_LibOpen, _LibClose, _LibExpunge, NULL,
lOpenQInts , /* -30 */
lCloseQInts , /* -36 A0 */
lSetQPri , /* -42 D0/D1 */
lSetQVector , /* -48 D0/D1/D2/D3/A0 */
NULL,
NULL,
NULL,
NULL,
lGetHead , /* -78 A0 */
lGetTail , /* -84 A0 */
lGetSucc , /* -90 A0 */
lGetPred , /* -96 A0 */
lGetHeadOff , /* -102 D0/D1 */
lGetTailOff , /* -108 D0/D1 */
lGetSuccOff , /* -114 D0/D1 */
lGetPredOff , /* -120 D0/D1 */
lEnqueueLong , /* -126 D0/D1/D2/D4 */
lEnqueueOffLong , /* -132 D0/D1/D2/D3/D4 */
lSearchFwdNode , /* -138 D0/D1/A1 */
lSearchRvsNode , /* -144 D0/D1/A1 */
lSearchFwdList , /* -150 D0/D1/A1 */
lSearchRvsList , /* -156 D0/D1/A1 */
lSearchFwdNodeOff, /* -162 D0/D1/A0/A1 */
lSearchRvsNodeOff, /* -168 D0/D1/A0/A1 */
lSearchFwdListOff, /* -174 D0/D1/A0/A1 */
lSearchRvsListOff, /* -180 D0/D1/A0/A1 */
NULL,
NULL,
NULL,
NULL,
lBZero , /* -210 D0/D1 */
lBSet , /* -216 D0/D1/A0 */
lBMov , /* -222 D0/D1/A0 */
lBCmp , /* -228 D0/D1/A0 */
NULL,
NULL,
NULL,
NULL,
lWildCmp , /* -258 D0/D1 */
lWaitMsg , /* -264 A0 */
lCheckMsg , /* -270 A0 */
lCheckPort , /* -276 A0 */
lLockAddr , /* -282 A0 */
lLockAddrB , /* -288 D0/A0 */
lUnLockAddr , /* -294 A0 */
lUnLockAddrB , /* -300 D0/A0 */
lDoSyncMsg , /* -306 A0/A1 */
lFindName2 , /* -312 D0/A0 */
_lGetTaskData , /* -318 D0/D1 */
_lFreeTaskData , /* -324 D0 */
_lDateToS , /* -330 D0/D1/A0 */
_lSetFileDate , /* -336 D0/D1 */
NULL,
NULL,
NULL,
NULL,
_lOpenIPC , /* -366 D0/D1 */
_lCloseIPC , /* -372 D0 */
_lSendIPC , /* -378 D0/D1/D2/A0 */
_lSendIPC2 , /* -384 D0/D1 */
_lReplyIPC , /* -390 D0/D1/D2/A0 */
_lFreeIPC , /* -396 D0 */
_lDoIPC2 , /* -402 D0/D1/D2/A0 */
_lParseCmd , /* -408 D0/D1/D2/D3/D4/A0 */
_lFreeParseCmd , /* -414 D0 */
NULL,
NULL,
NULL,
NULL,
(long (*)())-1
};
\Rogue\Monster\
else
echo "will not over write core/libfuncs.h"
fi
if [ `wc -c core/libfuncs.h | awk '{printf $1}'` -ne 4739 ]
then
echo `wc -c core/libfuncs.h | awk '{print "Got " $1 ", Expected " 4739}'`
fi
if `test ! -s core/libtag.asm`
then
echo "writing core/libtag.asm"
cat > core/libtag.asm << '\Rogue\Monster\'
; Machine Generated File
; Tags for library routines which are in C
FAR DATA
public _lGetTaskData
public __lGetTaskData
__lGetTaskData:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1,-(sp)
bsr _lGetTaskData
addq.l #8,A7
movem.l (sp)+,D2/D3/A6
rts
public _lFreeTaskData
public __lFreeTaskData
__lFreeTaskData:
movem.l D2/D3/A6,-(sp)
move.l D0,-(sp)
bsr _lFreeTaskData
addq.l #4,A7
movem.l (sp)+,D2/D3/A6
rts
public _lDateToS
public __lDateToS
__lDateToS:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1/A0,-(sp)
bsr _lDateToS
add.w #12,A7
movem.l (sp)+,D2/D3/A6
rts
public _lSetFileDate
public __lSetFileDate
__lSetFileDate:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1,-(sp)
bsr _lSetFileDate
addq.l #8,A7
movem.l (sp)+,D2/D3/A6
rts
public _lOpenIPC
public __lOpenIPC
__lOpenIPC:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1,-(sp)
bsr _lOpenIPC
addq.l #8,A7
movem.l (sp)+,D2/D3/A6
rts
public _lCloseIPC
public __lCloseIPC
__lCloseIPC:
movem.l D2/D3/A6,-(sp)
move.l D0,-(sp)
bsr _lCloseIPC
addq.l #4,A7
movem.l (sp)+,D2/D3/A6
rts
public _lSendIPC
public __lSendIPC
__lSendIPC:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1/D2/A0,-(sp)
bsr _lSendIPC
add.w #16,A7
movem.l (sp)+,D2/D3/A6
rts
public _lSendIPC2
public __lSendIPC2
__lSendIPC2:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1,-(sp)
bsr _lSendIPC2
addq.l #8,A7
movem.l (sp)+,D2/D3/A6
rts
public _lReplyIPC
public __lReplyIPC
__lReplyIPC:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1/D2/A0,-(sp)
bsr _lReplyIPC
add.w #16,A7
movem.l (sp)+,D2/D3/A6
rts
public _lFreeIPC
public __lFreeIPC
__lFreeIPC:
movem.l D2/D3/A6,-(sp)
move.l D0,-(sp)
bsr _lFreeIPC
addq.l #4,A7
movem.l (sp)+,D2/D3/A6
rts
public _lDoIPC2
public __lDoIPC2
__lDoIPC2:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1/D2/A0,-(sp)
bsr _lDoIPC2
add.w #16,A7
movem.l (sp)+,D2/D3/A6
rts
public _lParseCmd
public __lParseCmd
__lParseCmd:
movem.l D2/D3/A6,-(sp)
movem.l D0/D1/D2/D3/D4/A0,-(sp)
bsr _lParseCmd
add.w #24,A7
movem.l (sp)+,D2/D3/A6
rts
public _lFreeParseCmd
public __lFreeParseCmd
__lFreeParseCmd:
movem.l D2/D3/A6,-(sp)
move.l D0,-(sp)
bsr _lFreeParseCmd
addq.l #4,A7
movem.l (sp)+,D2/D3/A6
rts
\Rogue\Monster\
else
echo "will not over write core/libtag.asm"
fi
if [ `wc -c core/libtag.asm | awk '{printf $1}'` -ne 2290 ]
then
echo `wc -c core/libtag.asm | awk '{print "Got " $1 ", Expected " 2290}'`
fi
if `test ! -s core/Makefile`
then
echo "writing core/Makefile"
cat > core/Makefile << '\Rogue\Monster\'
# Makefile for DRES.LIBRARY, AZTEC C 3.6a
#
# NOTE: You must have previously create the directory 'local' in your
# C include's directory and placed the distribution include/local
# directory there. The libref program must also have been compiled
SYMS= include:symbols.m
SYMC= include:local/makesymbols.c
CFLAGS= +BCDLp +I$(SYMS)
LREXE= srcc:libref
SRC0= library.c
SRC1= libtag.asm
SRC2= /src/misc.c
SRC3= /src/qint.asm
SRC4= /src/lists.asm
SRC5= /src/mem.asm
SRC6= /src/timedate.c
SRC7= /src/ipc.c
SRC8= /src/res.c
OBJ0= vd0:library.o
OBJ1= vd0:libtag.o
OBJ2= vd0:misc.o
OBJ3= vd0:qint.o
OBJ4= vd0:lists.o
OBJ5= vd0:mem.o
OBJ6= vd0:timedate.o
OBJ7= vd0:ipc.o
OBJ8= vd0:res.o
OBJS= $(OBJ0) $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6) $(OBJ7)
all: $(SYMS) $(LREXE) hlib $(OBJS)
ln +Q $(OBJS) -ldres -lcl32 -o libs:dres.library
hlib:
libref
assign this: /core
cd ram:
make
cd this:
assign this:
$(OBJ0): $(SRC0)
cc $(CFLAGS) $(SRC0) -o $(OBJ0)
$(OBJ1): $(SRC1)
as $(SRC1) -o $(OBJ1)
$(OBJ2): $(SRC2)
cc $(CFLAGS) $(SRC2) -o $(OBJ2)
$(OBJ3): $(SRC3)
as $(SRC3) -o $(OBJ3)
$(OBJ4): $(SRC4)
as $(SRC4) -o $(OBJ4)
$(OBJ5): $(SRC5)
as $(SRC5) -o $(OBJ5)
$(OBJ6): $(SRC6)
cc $(CFLAGS) $(SRC6) -o $(OBJ6)
$(OBJ7): $(SRC7)
cc $(CFLAGS) $(SRC7) -o $(OBJ7)
$(OBJ8): $(SRC8)
cc $(CFLAGS) $(SRC8) -o $(OBJ8)
$(SYMS): $(SYMC)
make -f include:local/Makefile
$(LREXE): /libref.c
cc +L +I$(SYMS) /libref.c -o T:libref.o
ln +Q T:libref.o -lsup32 -lc32 -o $(LREXE)
delete T:libref.o
\Rogue\Monster\
else
echo "will not over write core/Makefile"
fi
if [ `wc -c core/Makefile | awk '{printf $1}'` -ne 1591 ]
then
echo `wc -c core/Makefile | awk '{print "Got " $1 ", Expected " 1591}'`
fi
if `test ! -s core/func.def`
then
echo "writing core/func.def"
cat > core/func.def << '\Rogue\Monster\'
; Run Time Library Function definition file
;
; -Generate function table for MakeLibrary in C
; -Generate tags in assembly for C
1= libfuncs.h
2= ram:
3= libtag.asm
4= DResBase
5= comp:clib/dres.lib
funcs.reg
\Rogue\Monster\
else
echo "will not over write core/func.def"
fi
if [ `wc -c core/func.def | awk '{printf $1}'` -ne 224 ]
then
echo `wc -c core/func.def | awk '{print "Got " $1 ", Expected " 224}'`
fi
if `test ! -s core/library.c`
then
echo "writing core/library.c"
cat > core/library.c << '\Rogue\Monster\'
/*
* LIBRARY.C
*
* Example fully working library for Aztec C ... with comments (which is
* a miracle in itself). By Matthew Dillon. PUBLIC DOMAIN.
*
* Aztec Compile with +BCDLp
* +B No startup reference
* +C Large code
* +D Large data
* +L 32 bit Integers
* +p compatibility mode (D2/D3 preserved)
*
* Since Original release, the following has been fixed:
* -slight bug in LibClose() .. did not expunge library if DELEXP set
* on final close. (thanks to Rico Mariani for finding the bug)
* -Now uses MakeLibrary call rather than a hardwired Library structure.
*/
#define NULL 0L
typedef struct Library LIB;
extern LIB *MakeLibrary();
#define VERSION 1 /* NOTE! String in dc.b below must also be */
#define REVISION 3 /* Changed! */
#asm
VERSION equ 1
; RLIB.ASM
;
; Run-time library tag
FAR data
public _CInit
public _LibOpen
public _LibClose
public _LibExpunge
Start: clr.l D0
rts
InitDesc: dc.w $4AFC ;RTC_MATCHWORD
dc.l InitDesc ;Pointer to beginning
dc.l EndCode ;Note sure it matters
dc.b 0 ;flags (NO RTF_AUTOINIT)
dc.b VERSION ;version
dc.b 9 ;NT_LIBRARY
dc.b 0 ;priority (doesn't matter)
dc.l _Libname ;Name of library
dc.l _Libid ;ID string (note CR-LF at end)
dc.l Init ;Pointer to init routine
_Libname: dc.b "dres.library",0
_Libid: dc.b "dres.library 1.3 (29 Sep 1988)",13,10,0
EndCode:
Init: move.l A6,-(sp) ;Must save A6
move.l A0,-(sp) ;Segment list
jsr _CInit
addq.l #4,sp
move.l (sp)+,A6
rts
cifc macro
move.l D0,-(sp) ;Make a C call and save A6 to boot
move.l A6,-(sp)
jsr \1
move.l (sp)+,A6
addq.l #4,sp
rts
endm
__LibOpen: cifc _LibOpen
__LibClose: cifc _LibClose
__LibExpunge: cifc _LibExpunge
#endasm
extern char Libname[1];
extern char Libid[1];
LIB *Lib, *DResBase; /* Library Base pointer */
long Seglist; /* Save the DOS seglist */
/*
* The Initialization routine is given only a seglist pointer. Since
* we are NOT AUTOINIT we must construct and add the library ourselves
* and return either NULL or the library pointer. Exec has Forbid()
* for us during the call.
*
* If you have an extended library structure you must specify the size
* of the extended structure in MakeLibrary().
*/
#include "libfuncs.h"
LIB *
CInit(segment)
{
extern long SysBase;
extern long DOSBase;
SysBase = *(long *)4;
DOSBase = OpenLibrary("dos.library", 0);
if (DOSBase == NULL)
return(NULL);
DResBase = Lib = MakeLibrary(LibVectors,NULL,NULL,sizeof(LIB),NULL);
Lib->lib_Node.ln_Type = NT_LIBRARY;
Lib->lib_Node.ln_Name = Libname;
Lib->lib_Flags = LIBF_CHANGED|LIBF_SUMUSED;
Lib->lib_Version = VERSION;
Lib->lib_Revision = REVISION;
Lib->lib_IdString = (APTR)Libid;
Seglist = segment;
AddLibrary(Lib);
return(Lib);
}
/*
* Open is given the library pointer and the version request. Either
* return the library pointer or NULL. Remove the DELAYED-EXPUNGE flag.
* Exec has Forbid() for us during the call.
*/
LIB *
LibOpen(lib,version)
LIB *lib;
{
++lib->lib_OpenCnt;
lib->lib_Flags &= ~LIBF_DELEXP;
return(lib);
}
/*
* Close is given the library pointer and the version request. Be sure
* not to decrement the open count if already zero. If the open count
* is or becomes zero AND there is a LIBF_DELEXP, we expunge the library
* and return the seglist. Otherwise we return NULL.
*
* Note that this routine never sets LIBF_DELEXP on its own.
*
* Exec has Forbid() for us during the call.
*/
LibClose(lib)
LIB *lib;
{
if (lib->lib_OpenCnt && --lib->lib_OpenCnt)
return(NULL);
if (lib->lib_Flags & LIBF_DELEXP)
return(LibExpunge(lib));
return(NULL);
}
/*
* We expunge the library and return the Seglist ONLY if the open count
* is zero. If the open count is not zero we set the DELAYED-EXPUNGE
* flag and return NULL.
*
* Exec has Forbid() for us during the call. NOTE ALSO that Expunge
* might be called from the memory allocator and thus we CANNOT DO A
* Wait() or otherwise take a long time to complete (straight from RKM).
*
* Apparently RemLibrary(lib) calls our expunge routine and would
* therefore freeze if we called it ourselves. As far as I can tell
* from RKM, LibExpunge(lib) must remove the library itself as shown
* below.
*/
LibExpunge(lib)
LIB *lib;
{
extern long DOSBase;
if (lib->lib_OpenCnt) {
lib->lib_Flags |= LIBF_DELEXP;
return(NULL);
}
if (DOSBase) {
CloseLibrary(DOSBase);
DOSBase = NULL;
}
Remove(lib);
FreeMem((char *)lib-lib->lib_NegSize, lib->lib_NegSize+lib->lib_PosSize);
return(Seglist);
}
\Rogue\Monster\
else
echo "will not over write core/library.c"
fi
if [ `wc -c core/library.c | awk '{printf $1}'` -ne 4923 ]
then
echo `wc -c core/library.c | awk '{print "Got " $1 ", Expected " 4923}'`
fi
if `test ! -s libref.c`
then
echo "writing libref.c"
cat > libref.c << '\Rogue\Monster\'
/*
* LIBREF.C
*
* LIBREF [cmdfile]
* (default func.def)
*/
#include <stdio.h>
#include <fcntl.h>
#include <local/typedefs.h>
#define FLIST struct _FLIST
FLIST {
MNODE Node;
uword RegMask;
uword IsAsm;
char FName[64];
};
extern char *MToS();
char LibGlob[64] = { "SomeUnknownLibBase" };
char MName[128] = { "ram:MakeLib.c" };
char LName[128] = { "ram:LinkTag.asm" };
char TName[128] = { "ram:LibTag.asm" };
char LibName[128] = { "ram:Lib.lib" };
MLIST FBase;
main(ac,av)
char *av[];
{
FILE *fi;
char *file = "func.def";
char buf[128];
puts("LIBREF V1.00 Sept 1988, (c)Copyright 1988 Matthew Dillon, All Rights Reserved");
puts(" source/executable Freely distributable for non-profit only. May be USED");
puts(" in-house to generate commercial libraries.");
NewList(&FBase);
if (ac == 2)
file = av[1];
fi = fopen(file, "r");
if (!fi) {
printf("%s not found\n", file);
puts("LIBREF [cmdfile]");
exit(1);
}
while (fgets(buf, sizeof(buf), fi)) {
buf[strlen(buf)-1] = 0;
if (!buf[0] || buf[0] == ';')
continue;
switch((buf[0]<<8)|buf[1]) {
case '1=':
sscanf(buf+2, "%s", MName);
break;
case '2=':
sscanf(buf+2, "%s", LName);
break;
case '3=':
sscanf(buf+2, "%s", TName);
break;
case '4=':
sscanf(buf+2, "%s", LibGlob);
break;
case '5=':
sscanf(buf+2, "%s", LibName);
break;
case '6=':
case '7=':
case '8=':
case '9=':
break;
default:
scanfile(buf, buf, sizeof(buf));
break;
}
}
fclose(fi);
{
FILE *fi = fopen(MName, "w");
if (!fi) {
printf("Unable to open %s for write\n", MName);
exit(-1);
}
GenerateMakeLib(fi);
fclose(fi);
fi = fopen(TName, "w");
if (!fi) {
printf("Unable to open %s for write\n", MName);
exit(-1);
}
GenerateTags(fi);
fclose(fi);
GenerateLinkLib(LName, strlen(LName));
}
}
/*
* scan file for functions
*
* *FUNC=NAME REGS (C, assembly tag entry, add extra _)
* ;FUNC=NAME REGS (assembly, direct entry)
* D0-2/A0/A1/A2 ...
* REGISTERS ALWAYS LOADED D0-D7,A0-A7 (A6,A7 cannot be used)
*
* starting within the first 16 lines of the file.
*/
scanfile(file, buf, bufsize)
char *file;
char *buf;
long bufsize;
{
FILE *fi;
short i;
fi = fopen(file, "r");
if (!fi) {
printf("Unable to open file %s\n", file);
return(-1);
}
for (i = 0; i < 16; ++i) {
short isasm;
short j;
if (fgets(buf, bufsize, fi) == NULL)
return(0);
for (j = 0; buf[j] == ' ' || buf[j] == 9; ++j);
isasm = (buf[j] == ';' || buf[j] == 'A');
++j;
if (strncmp(buf+j, "FUNC=", 5) == 0) {
i = 0;
AddFunction(buf+j+5, isasm);
}
}
fclose(fi);
}
/*
* FuncName Regs (NULL SPECIAL)
*/
AddFunction(buf, isasm)
char *buf;
{
char fname[64];
char regs[64];
uword regmask = 0; /* A7-A0,D7-D0 */
if (sscanf(buf, "%s %s", fname, regs) != 2) {
printf("Argument Error: %s\n", buf);
return(-1);
}
if (strcmp(regs, "-") == 0)
regs[0] = 0;
{
register short i;
register short s, e;
for (i = 0; regs[i]; ) {
s = e = regs[i+1] - '0';
if (s < 0 || s > 7)
goto fail;
switch(regs[i]) {
case 'A':
s += 8;
e += 8;
i += 2;
if (regs[i] == '-') {
if (regs[i+1] != 'A')
goto fail;
e = regs[i+2] - '0';
if (e < 0 || e > 7)
goto fail;
e += 8;
i += 3;
}
break;
case 'D':
i += 2;
if (regs[i] == '-') {
if (regs[i+1] != 'D')
goto fail;
e = regs[i+2] - '0';
if (e < 0 || e > 7)
goto fail;
i += 3;
}
break;
default:
goto fail;
}
while (s <= e) {
regmask |= 1 << s;
++s;
}
if (regs[i]) {
if (regs[i] != '/')
goto fail;
++i;
}
}
}
/*
printf("Function: %-10s Regs: %04x Asm: %d\n", fname, regmask, isasm);
*/
{
register FLIST *fl = malloc(sizeof(FLIST));
if (fl) {
fl->RegMask = regmask;
fl->IsAsm = isasm;
if (strcmp(fname, "NULL") == 0)
fl->FName[0] = 0;
else
strcpy(fl->FName, fname);
AddTail(&FBase, fl);
}
}
return(0);
fail:
printf("Bad Register Spec: %s\n", buf);
return(-1);
}
GenerateMakeLib(fi)
FILE *fi;
{
register FLIST *fl;
short i;
fprintf(fi, "\n/*\n * Machine Generated Library Vectors\n */\n\n");
fprintf(fi, "#ifndef NULL\n#define NULL 0L\n#endif\n\n");
fprintf(fi, "extern long _LibOpen(), _LibClose(), _LibExpunge();\n");
for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
if (fl->FName[0]) {
if (fl->IsAsm) { /* If assembly, direct reference */
fprintf(fi, "extern long l%s();\n", fl->FName);
} else { /* If not, reference to tag */
fprintf(fi, "extern long _l%s();\n", fl->FName);
}
}
}
fprintf(fi, "\n\n/*\n * -30-6*X\n */\n\n");
fprintf(fi, "long (*LibVectors[])() = {\n");
fprintf(fi, " _LibOpen, _LibClose, _LibExpunge, NULL,\n\n");
for (i = 0, fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
if (fl->FName[0]) {
if (fl->IsAsm)
fprintf(fi, " l%-16s, /* %3ld %-20s */\n", fl->FName, -30-6*i, MToS(fl->RegMask));
else
fprintf(fi, " _l%-15s, /* %3ld %-20s */\n", fl->FName, -30-6*i, MToS(fl->RegMask));
} else {
fprintf(fi, " NULL,\n");
}
++i;
}
fprintf(fi, " (long (*)())-1\n};\n\n");
}
GenerateTags(fi)
FILE *fi;
{
register FLIST *fl;
fprintf(fi, "\n");
fprintf(fi, "\t; Machine Generated File\n");
fprintf(fi, "\t; Tags for library routines which are in C\n\n");
fprintf(fi, "\tFAR\tDATA\n\n");
for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
uword mask;
if (fl->IsAsm || !fl->FName[0])
continue;
fprintf(fi, "\n");
fprintf(fi, "\t\tpublic _l%s\n\t\tpublic __l%s\n\n", fl->FName, fl->FName);
fprintf(fi, "__l%s:\n", fl->FName);
/*
* Save the set D2/D3/A6, but don't bother saving D2 or
* D2 and D3 if passed as arguments.
*/
mask = 0x400C;
MoveToStack(fi, mask); /* Save some args */
MoveToStack(fi, fl->RegMask); /* Push some args */
fprintf(fi, "\t\tbsr\t_l%s\n", fl->FName);
PopStack(fi, fl->RegMask);
MoveFromStack(fi, mask);
fprintf(fi,"\t\trts\n");
}
}
/*
* Generate the link library. Create N output modules for
* each function reference by appending a number to the name
*/
GenerateLinkLib(dir, dirlen)
char *dir;
short dirlen;
{
char tmp[128];
short i, nobj, nj;
FILE *fi;
FILE *fi2;
register FLIST *fl;
register short off;
strcpy(dir+dirlen, "Makefile");
fi = fopen(dir, "w");
if (!fi)
goto fail;
strcpy(dir+dirlen, "Ordin");
fi2 = fopen(dir, "w");
if (!fi2)
goto fail;
fputs("\nAFLAGS = -D\n\n", fi);
nj = 0;
nobj = 1;
for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
if (!fl->FName[0])
continue;
fprintf(fi2, "%s.o\n", fl->FName);
if (nj == 0)
fprintf(fi, "OBJ%d = ", nobj);
fprintf(fi, "%s.o ", fl->FName);
nj += strlen(fl->FName) + 3;
if (nj > 70) {
fprintf(fi, "\n");
nj = 0;
++nobj;
}
}
fprintf(fi2, "lvo.o\n");
if (nj == 0)
fprintf(fi, "OBJ%d = ", nobj);
fprintf(fi, "lvo.o\n");
fclose(fi2);
fprintf(fi, "\nall:\t");
for (i = 1; i <= nobj; ++i) {
fprintf(fi, "$(OBJ%d) ", i);
}
fprintf(fi, "\n");
fprintf(fi, "\tord %s ", dir);
strcpy(dir+dirlen, "Ordout");
fprintf(fi, "\t%s\n", dir);
fprintf(fi, "\t-Delete %s\n", LibName);
fprintf(fi, "\tlb %s -f %s\n", LibName, dir);
strcpy(dir+dirlen, "lvo.asm");
fclose(fi);
fi = fopen(dir, "w");
if (!fi)
goto fail;
for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
if (fl->FName[0])
fprintf(fi, "\t\tpublic\t_LVO%s\n", fl->FName);
}
for (off = -30, fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
if (!fl->FName[0]) {
off -= 6;
continue;
}
sprintf(tmp, "_LVO%s", fl->FName);
fprintf(fi, "%-24s\tequ\t%d\n", tmp, off);
off -= 6;
}
fclose(fi);
for (fl = (FLIST *)FBase.mlh_Head; (APTR)fl != (APTR)&FBase.mlh_Tail; fl = (FLIST *)fl->Node.mln_Succ) {
if (!fl->FName[0])
continue;
strcpy(dir+dirlen, "TEMP");
strcpy(tmp, dir);
strcpy(dir+dirlen, fl->FName);
strcat(dir+dirlen, ".asm");
fi = fopen(tmp, "w");
if (!fi)
goto fail;
fprintf(fi,"\n; Machine Generated Link Tag\n\n");
fprintf(fi,"\t\tFAR\tDATA\n");
fprintf(fi,"\t\tpublic\t_LVO%s\n", fl->FName);
fprintf(fi,"\t\tpublic\t_%s\n", LibGlob);
fprintf(fi,"\t\tpublic\t_%s\n\n", fl->FName);
fprintf(fi,"_%s:\n", fl->FName);
/*
* Generate linker tag to assembly. If neither A0 or A1 is
* used as an argument, use one as the link register, else
* save A6 and use that.
*
* If A2-A6 (inc A6 above), D2-D6 are required to hold
* parameters, they are saved before the call, restored
* after. If they are not required to hold any parameters,
* a JMP is issued instead of a JSR.
*/
{
uword argmask = fl->RegMask;
uword savmask = fl->RegMask;
short areg = 6;
if (!(argmask & 0x0100)) /* A0 not used */
areg = 0;
if (!(argmask & 0x0200)) /* A1 not used */
areg = 1;
savmask |= 1 << (areg+8); /* Add register usage */
MoveToStack(fi, savmask & 0xFCFC); /* save some regs */
LoadFromStack(fi, argmask, 4+Offset(argmask & 0xFCFC)); /* load params */
fprintf(fi,"\t\tmove.l\t_%s,A%d\n", LibGlob, areg);
if (savmask & 0xFCFC) {
fprintf(fi, "\t\tjsr\t_LVO%s(A%d)\n", fl->FName, areg);
MoveFromStack(fi, savmask & 0xFCFC); /* restore some regs */
fprintf(fi,"\t\trts\n");
} else {
fprintf(fi, "\t\tjmp\t_LVO%s(A%d)\n", fl->FName, areg);
}
}
fclose(fi);
if (cmp_file(tmp, dir) == 0) { /* update only if changed */
DeleteFile(dir);
Rename(tmp, dir);
}
}
return(0);
fail:
printf("Unable to open %s\n", dir);
return(-1);
}
char *
MToS(mask)
register uword mask;
{
register short i;
register short j = 0;
static char buf[64];
for (i = 0; i < 8; ++i, mask >>= 1) {
if (mask & 1) {
if (j)
buf[j++] = '/';
buf[j++] = 'D';
buf[j++] = i + '0';
}
}
for (i = 0; i < 8; ++i, mask >>= 1) {
if (mask & 1) {
if (j)
buf[j++] = '/';
buf[j++] = 'A';
buf[j++] = i + '0';
}
}
buf[j++] = 0;
return(buf);
}
MoveToStack(fi, mask)
FILE *fi;
{
char *str = MToS(mask);
if (!str[0])
return(0);
if (!str[2]) {
fprintf(fi, "\t\tmove.l\t%s,-(sp)\n", str);
} else {
fprintf(fi, "\t\tmovem.l\t%s,-(sp)\n", str);
}
}
MoveFromStack(fi, mask)
FILE *fi;
uword mask;
{
char *str = MToS(mask);
if (!str[0])
return(0);
if (!str[2])
fprintf(fi, "\t\tmove.l\t(sp)+,%s\n", str);
else
fprintf(fi, "\t\tmovem.l\t(sp)+,%s\n", str);
}
LoadFromStack(fi, mask, offset)
{
char *str = MToS(mask);
if (!str[0])
return(0);
if (!str[2])
fprintf(fi, "\t\tmove.l\t%d(sp),%s\n", offset, str);
else
fprintf(fi, "\t\tmovem.l\t%d(sp),%s\n", offset, str);
}
PopStack(fi, mask)
FILE *fi;
uword mask;
{
register short j;
if (j = Offset(mask)) {
if (j > 8)
fprintf(fi,"\t\tadd.w\t#%d,A7\n", j);
else
fprintf(fi,"\t\taddq.l\t#%d,A7\n", j);
}
}
Offset(mask)
uword mask;
{
register short i, j;
for (i = j = 0; i < 16; ++i) {
if (mask & (1 << i))
++j;
}
return(j*4);
}
cmp_file(name1, name2)
char *name1;
char *name2;
{
short i, fd1, fd2;
static char buf1[1024];
static char buf2[1024];
fd1 = open(name1, O_RDONLY);
if (fd1 < 0)
return(0);
fd2 = open(name2, O_RDONLY);
if (fd2 < 0) {
close(fd1);
return(0);
}
while ((i = read(fd1, buf1, sizeof(buf1))) > 0) {
if (read(fd2, buf2, i) != i)
goto fail;
if (bcmp(buf1, buf2, i) == 0)
goto fail;
}
if (read(fd2, buf2, 1) != 0)
goto fail;
close(fd1);
close(fd2);
return(1);
fail:
close(fd1);
close(fd2);
return(0);
}
\Rogue\Monster\
else
echo "will not over write libref.c"
fi
if [ `wc -c libref.c | awk '{printf $1}'` -ne 12306 ]
then
echo `wc -c libref.c | awk '{print "Got " $1 ", Expected " 12306}'`
fi
echo "Finished archive 3 of 3"
# if you want to concatenate archives, remove anything after this line
exit
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.